package cn.bluethink.eguan.core.service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;

import cn.bluethink.eguan.core.entity.EgMemberEntity;
import cn.bluethink.eguan.core.entity.MemberEntity;
import cn.bluethink.eguan.core.mapper.EgMemberMapper;
import cn.bluethink.eguan.filter.NameFilter;
import cn.bluethink.eguan.model.core.EgConfigInfo;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgObject;
import cn.bluethink.eguan.model.core.EgRole;
import cn.bluethink.eguan.model.core.EgScope;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.result.PageInfo;
import tk.mybatis.mapper.entity.Example;

/**
 * 门派成员业务层
 * 
 * @author 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.1.0
 * @note 修订历史： 1、wanglei于2018/10/13设计并构建初始版本v0.1.0
 */
@Service
public class EgMemberService extends AEgUserPurviewService {

    @Autowired
    private EgConfigInfo configInfo;

    @Autowired
    private EgMemberMapper memberMapper;

    public EgMemberService() {
        super();
    }

    @Override
    public Integer posOType() {
        // 返回门派对象类型的ID
        return EgOType.FACTION;
    }

    @Override
    public EgRole role(EgObject pos, Long uid, EgRole urole) throws Exception {
        // 1、获取用户当前角色权限
        EgRole crole = new EgRole(urole.getRid(), urole.getName(), urole.getPurview());
        // 根据门派ID和成员ID查询用户信息
        EgUser member = this.queryById(pos.getId(), uid);
        if (member == null) {
            // 如果用户不在当前门派，计算并设置当前用户在门派中的角色名
            crole.setName(configInfo.roleName(urole.getRid(), EgScope.FACTION));
            return null;
        } else {
            // 如果用户在当前门派，根据当前用户角色和门派角色进行计算，获得用户在当前门派中的角色和权限
            EgRole role = new EgRole(crole.getRid(), crole.getName(), crole.getPurview());
            role.or(member.getRole());
            // 设置当前用户的角色名
            role.setName(configInfo.roleName(role.getRid(), EgScope.FACTION));
            return role;
        }
    }

    /**
     * 创建门派成员信息
     * 
     * @param fid
     * @param uid
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgUser create(Long fid, Long uid) throws Exception {
        // 创建门派成员时，默认的角色为成员，权限值为0
        EgRole defaultRole = configInfo.role(EgRole.MEMBER).get(EgScope.FACTION);
        EgMemberEntity entity = new EgMemberEntity(fid, uid, defaultRole.getRid(), defaultRole.getPurview());
        int insertCount = memberMapper.insertSelective(entity);
        return insertCount > 0 ? entity.createMember() : null;
    }

    /**
     * 更新门派成员信息 角色和权限
     * 
     * @param fid
     * @param uid
     * @param role2
     * @param purview2
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgUser update(Long fid, Long uid, Integer role2, Integer purview2) throws Exception {
        // 创建实体
        EgMemberEntity entity = new EgMemberEntity(fid, uid, role2, purview2);
        int updateCount = memberMapper.updateByPrimaryKeySelective(entity);
        return updateCount > 0 ? entity.createMember() : null;
    }

    /**
     * 根据门派ID和成员ID查询门派成员信息
     * 
     * @param fid
     * @param uid
     * @return
     * @throws Exception
     */
    public EgUser queryById(Long fid, Long uid) throws Exception {
        Example example = new Example(EgMemberEntity.class);
        example.and().andEqualTo("fid", fid).andEqualTo("uid", uid);
        EgMemberEntity entity = memberMapper.selectOneByExample(example);
        return entity != null ? entity.createMember() : null;
    }

    /**
     * 根据门派ID和角色ID查询成员信息
     * 
     * @param fid
     * @param role2
     * @return
     * @throws Exception
     */
    public EgUser queryByRole(Long fid, Integer role2) throws Exception {
        Example example = new Example(EgMemberEntity.class);
        example.and().andEqualTo("fid", fid).andEqualTo("role2", role2);
        EgMemberEntity entity = memberMapper.selectOneByExample(example);
        return entity != null ? entity.createMember() : null;
    }

    /**
     * 根据门派ID和成员Id移除门派成员
     * 
     * @param fid
     * @param uid
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean remove(Long fid, Long uid) throws Exception {
        Example example = new Example(EgMemberEntity.class);
        example.and().andEqualTo("fid", fid).andEqualTo("uid", uid);
        // 删除门派成员
        int deletCount = memberMapper.deleteByExample(example);
        if (deletCount == 0) {
            return false;
        }
        return true;
    }

    /**
     * 根据门派ID删除门派的所有成员
     * 
     * @param fid
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public Boolean del(Long fid) throws Exception {
        Example example = new Example(EgMemberEntity.class);
        example.and().andEqualTo("fid", fid);
        int deletCount = memberMapper.deleteByExample(example);
        return deletCount > 0 ? true : false;
    }

    /**
     * 设置成员角色 (设置为副帮主或门派成员)
     * 
     * @param fid
     * @param uid
     * @param rid
     * 
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgUser setrole(Long fid, Long uid, Integer rid) throws Exception {
        // 查询门派成员信息
        EgUser user = queryById(fid, uid);
        if (user == null) {
            return null;
        }
        // 获取被设置用户的原有角色/门派中默认成员角色/门派中默认副帮主角色
        EgRole userRole = user.getRole();
        EgRole memberRole = configInfo.role(EgRole.MEMBER).get(EgScope.FACTION);
        EgRole viceCheafRole = configInfo.role(EgRole.VICE_CHEAF).get(EgScope.FACTION);
        // 如果设置为副帮主,"或"运算得到最终
        if (rid.equals(EgRole.VICE_CHEAF)) {
            userRole.or(viceCheafRole);
        }
        // 如果设置为普通成员
        else if (rid.equals(EgRole.MEMBER)) {
            // 如果其之前为副帮主，"异或"运算去除原有
            if ((userRole.getRid() & EgRole.VICE_CHEAF) > 0) {
                userRole.xor(viceCheafRole);
            }
            // "或"运算得到最终
            userRole.or(memberRole);
        }
        // 更新当前用户的角色和权限信息
        user = update(fid, uid, userRole.getRid(), userRole.getPurview());
        return user != null ? user : null;
    }

    /**
     * 根据条件查询门派成员列表，包括成员角色信息，账户信息，经验值，技能值
     * 
     * @param filter
     * @param bLoadRole
     * @return
     * @throws Exception
     */
    public PageInfo<EgUser> query(NameFilter filter, Boolean bLoadRole) throws Exception {
        Integer pageNum = filter.getPageNum() == null ? 1 : filter.getPageNum();
        Integer pageSize = filter.getPageSize() == null ? 50 : filter.getPageSize();
        Long id = filter.getId() == null ? 0 : filter.getId();
        Boolean buid = filter.getBuid() == null ? false : filter.getBuid();
        String name = filter.getName();
        // 返回结果
        List<EgUser> result = new ArrayList<>();
        // 分页
        PageHelper.startPage(pageNum, pageSize);
        List<MemberEntity> entities = memberMapper.selectMembersByCondition(id, buid, name);
        PageInfo<MemberEntity> oldPageInfo = new PageInfo<>(entities);
        if (entities != null && entities.size() > 0) {
            // 实体转换为模型列表
            result = entities.stream().map(e -> e.createUser()).collect(Collectors.toList());
            // 如果不加载角色信息，直接返回结果
            if (!bLoadRole) {
                return new PageInfo<>(result, oldPageInfo);
            }
            // 否则，设置角色信息
            result.forEach(r -> {
                String rname = configInfo.roleName(r.getRole().getRid().intValue(), EgScope.FACTION);
                r.getRole().setName(rname);
            });
        }
        return new PageInfo<>(result, oldPageInfo);
    }

    /**
     * 批量新增成员，目前只用于升级驿馆
     * 
     * @param fid
     * @param users
     * @param shopkeeper
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public boolean batchAdd(Long fid, List<EgUser> users, EgUser shopkeeper) throws Exception {
        EgRole memberRole = configInfo.role(EgRole.MEMBER).get(EgScope.FACTION);
        EgRole cheafRole = configInfo.role(EgRole.CHEAF).get(EgScope.FACTION);
        // 将用户角色权限设置为门派成员角色；将掌柜角色权限设置为门派帮主
        users.forEach(u -> {
            Long uid = u.getId();
            if (shopkeeper != null && uid.equals(shopkeeper.getId())) {
                u.setRole(cheafRole);
            } else {
                u.setRole(memberRole);
            }
        });
        // 将用户转为成员实体
        List<EgMemberEntity> entities = users.stream()
                .map(u -> new EgMemberEntity(fid, u.getId(), u.getRole().getRid(), u.getRole().getPurview()))
                .collect(Collectors.toList());
        if (memberMapper.insertMembers(entities) > 0) {
            return true;
        }
        return false;
    }
}
